package thread;

// 懒汉模式 有线程安全问题
class SingletonLazy {
    /*
        volatile 必须加 不然会出现指令重排序导致的问题
        new: 1. 申请内存 2. 初始化 3. 返回地址
        如果指令重排序后是 132 那么就有在问题
        当执行完13的时候 另一个线程执行第一个if语句并返回值 那么这个返回值指向的对象的错误的
        所以如果此时执行内部的方法 那么就会出现问题
     */
    private volatile static SingletonLazy instance = null;

    private static final Object locker = new Object();

    public static SingletonLazy getInstance() {
        // 思考：为什么有两个 instance == null
        if (instance == null) { // 第一个是为了判断是否应该加锁 提高效率
            synchronized (locker) {
                if (instance == null) { // 第二个是为了判断此时是否应该实例化
                    instance = new SingletonLazy();
                }
            }
        }
        // 总结：因为这两个情况下的判断条件（凑巧）是一致的
        return instance;
    }
    private SingletonLazy() {}
}

public class Demo27 {
    public static void main(String[] args) {
        SingletonLazy s1 = SingletonLazy.getInstance();
        SingletonLazy s2 = SingletonLazy.getInstance();
        System.out.println(s1 == s2);
//        new SingletonLazy(); // err
    }
}
